package stone926.mods.more_enchantments.mixins;

import net.minecraft.entity.AreaEffectCloudEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import stone926.mods.more_enchantments.interfaces.IAreaEffectCloudEntityFilterEntity;

import java.util.UUID;

import static stone926.mods.more_enchantments.nbt.CustomNbtKeys.AREA_EFFECT_CLOUD.ENTITY_DO_NOT_AFFECT;

@Mixin(AreaEffectCloudEntity.class)
public abstract class AreaEffectCloudEntityMixin extends Entity implements IAreaEffectCloudEntityFilterEntity {

  private UUID entityDoNotAffectUuid = null;

  public AreaEffectCloudEntityMixin(EntityType<?> type, World world) {
    super(type, world);
  }

  @Override
  public UUID getEntityDoNotAffect() {
    return entityDoNotAffectUuid;
  }

  @Override
  public void setEntityDoNotAffect(UUID entityDoNotAffect) {
    entityDoNotAffectUuid = entityDoNotAffect;
  }

  @Inject(method = "readCustomDataFromNbt", at = @At("HEAD"))
  private void readCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {
    if (nbt.contains(ENTITY_DO_NOT_AFFECT)) setEntityDoNotAffect(nbt.getUuid(ENTITY_DO_NOT_AFFECT));
  }

  @Inject(method = "writeCustomDataToNbt", at = @At("HEAD"))
  private void writeCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) {
    if (getEntityDoNotAffect() != null) nbt.putUuid(ENTITY_DO_NOT_AFFECT, getEntityDoNotAffect());
  }

  @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;addStatusEffect(Lnet/minecraft/entity/effect/StatusEffectInstance;Lnet/minecraft/entity/Entity;)Z"))
  public boolean redirectAddStatusEffect(LivingEntity livingEntity, StatusEffectInstance effect, Entity source) {
    if (livingEntity.getUuid().equals(getEntityDoNotAffect()) && !(effect.getEffectType().isBeneficial())) return false;
    return livingEntity.addStatusEffect(effect, source);
  }

  @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/effect/StatusEffect;applyInstantEffect(Lnet/minecraft/entity/Entity;Lnet/minecraft/entity/Entity;Lnet/minecraft/entity/LivingEntity;ID)V"))
  public void redirectApplyInstantEffect(StatusEffect statusEffect, Entity source, Entity attacker, LivingEntity target, int amplifier, double proximity) {
    if (target.getUuid().equals(getEntityDoNotAffect()) && !(statusEffect.isBeneficial())) return;
    statusEffect.applyInstantEffect(source, attacker, target, amplifier, proximity);
  }

}
